home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / MNetsrc.hqx / Mac TCP_IP Source v.33 / mac_help.c < prev    next >
C/C++ Source or Header  |  1989-02-19  |  20KB  |  830 lines

  1. #include <QuickDraw.h>
  2. #include <MacTypes.h>
  3. #include <DialogMgr.h>
  4. #include <WindowMgr.h>
  5. #include <DialogMgr.h>
  6. #include <EventMgr.h>
  7. #include <MemoryMgr.h>
  8. #include <TextEdit.h>
  9. #include <StdFilePkg.h>
  10. #include <MenuMgr.h>
  11. #include <ListMgr.h>
  12. #include <FontMgr.h>
  13. #include <ToolBoxUtil.h>
  14. #include <ControlMgr.h>
  15. #include <ResourceMgr.h>
  16.  
  17. typedef struct{
  18.     ListHandle        helpList;
  19.     int                helpDlogType;
  20.     ControlHandle    ScrollHdl;
  21.     int                scrollAmt;
  22.     int                scrollCode;
  23.     int                linesVis;
  24.     TEHandle        hTE;
  25.     PicHandle        helpPict;
  26.     Rect            pictRect;
  27. } DlogInfo, *DlogIPtr, **DlogIHdl;
  28.  
  29. typedef struct {
  30.     int                topicsID;
  31.     int                infoID;
  32.     int                locateID;
  33.     Point            text1Loc;
  34.     Point            text2Loc;
  35.     Point            text3Loc;
  36.     int                topicFont;
  37.     int                topicSize;
  38.     Rect            topicRect;
  39.     int                textFont;
  40.     int                textSize;
  41.     int                titleFont;
  42.     int                titleSize;
  43.     int                titleFace;
  44.     Rect            titleRect;
  45.     Rect            textRect;
  46. } HelpTemplate, *HTPtr, **HTHdl;
  47.  
  48. #define TEMPLATE 500
  49. #define HELPMENU 30001
  50. #define ScrlLine 10
  51. #define NIL 0L
  52. #define QuitHelp 0
  53. enum {    HELPTOPICS,HELPWINDOW    };
  54. enum {    TOPICS=1,
  55.         NEXT,
  56.         PREVIOUS,
  57.         HELPCANCEL };
  58. enum {    PictNotFound=-606,
  59.         HMgrNotFound,
  60.         TopicsDlogErr,
  61.         TextDlogErr,
  62.         TextInsErr,
  63.         RsrcFileErr,
  64.         TemplateErr    };
  65.  
  66. static MenuHandle GLhelpMenu;
  67. static int helpResNum=-1;
  68. static Boolean needsClosing=TRUE;
  69.  
  70. pascal Boolean helpFilter();
  71. pascal void HelpScrollProc();
  72.  
  73.  
  74. /***********************************************************
  75. Do help on an application
  76.     1. helpFileName - help file name or null string to
  77.         look for help in CurResFile()
  78.     2. text1,text2,text3: 3 lines of text for topics
  79.         dialog box
  80.     3. styleText: True to use text edit with style, else
  81.         use old text edit (Style text requires System>4.0).
  82.     4. fileType: HMgr resource file SFFileType or 'ANYR'
  83.         to look for any resource file
  84.         
  85. ErrorCodes on return
  86.     noErr(0): no errors
  87.     PictNotFound(-606): Error accessing PICT resource
  88.     HMgrNotFound(-605): Error accessing HMgr resource
  89.     TopicsDlogErr(-604): could not create Help Topic dialog
  90.     TextDlogErr(-603): could not create Help Text dialog
  91.     TextInsErr(-602): could not insert Help text
  92.     RsrcFileErr(-601): could not open resource file
  93.     TemplateErr(-600): could not open Help Template
  94. ***********************************************************/
  95.  
  96. DoHelp(helpFileName,text1,text2,text3,styleText,fileType)
  97.     char *helpFileName,*text1,*text2,*text3;
  98.     Boolean styleText;
  99.     long fileType;
  100. {
  101.     GrafPtr save_graf;
  102.     int saveResNum,helpTopic,helpError;
  103.     
  104.     GetPort(&save_graf);
  105.     saveResNum=CurResFile();
  106.  
  107.     if(helpResNum<0)
  108.     {    if((helpError=OpenHelp(helpFileName,fileType))<=0)
  109.         {    SetPort(save_graf);
  110.             return(helpError);
  111.         }
  112.     }
  113.     UseResFile(helpResNum);
  114.     
  115.     helpTopic=1;
  116.     while ((helpTopic=GetHelpTopic(helpTopic,text1,
  117.                         text2,text3,GLhelpMenu))>QuitHelp)
  118.     {    if((helpTopic=ShowHelpTopic(helpTopic,styleText,
  119.                         GLhelpMenu))<=QuitHelp) break;
  120.     }
  121.  
  122.     UseResFile(saveResNum);
  123.     SetPort(save_graf);
  124.     return(helpTopic);
  125. }
  126.  
  127. /***********************************************************
  128.     If want to free some memory or if want to get help
  129.     using a different HMgr resource file, call this routine
  130.     to dispose of the previously opened HMgr file info
  131. ***********************************************************/
  132.  
  133. DisposeHelp()
  134. {
  135.     if(needsClosing)
  136.         CloseResFile(helpResNum);
  137.     helpResNum=-1;
  138.     needsClosing=TRUE;
  139.     DisposeMenu(GLhelpMenu);
  140. }
  141.     
  142. /***********************************************************
  143.     Open the HMgr resource file or if helpFileName is
  144.     empty use the HMgr resources in CurResFile()
  145. ***********************************************************/
  146.  
  147. static OpenHelp(helpFileName,fileType)
  148.     char *helpFileName;
  149.     long fileType;
  150. {
  151.     register int i;
  152.     Point upleft;
  153.     SFReply filetry;
  154.     DialogPtr dptr;
  155.     char volName[2];
  156.     HTHdl HT;
  157.     
  158.     HT=(HTHdl)GetResource('HTpl',TEMPLATE);
  159.     if(ResError()!=noErr)
  160.         return(TemplateErr);
  161.     
  162.     if(helpFileName[0]==0)
  163.     {    helpResNum=CurResFile();
  164.         needsClosing=FALSE;
  165.     }
  166.     else if((helpResNum=OpenResFile(helpFileName))<0)
  167.     {    upleft.v=85;
  168.         upleft.h=82;
  169.         volName[0]=0;
  170.         ParamText(helpFileName,"\p","\p","\p");
  171.         dptr=GetNewDialog((**HT).locateID,NIL,-1L);
  172.         DrawDialog(dptr);
  173.         if(fileType=='ANYR')
  174.             SFGetFile(upleft,"\pHelp",NIL,-1,fileType,
  175.                             NIL,&filetry);
  176.         else
  177.             SFGetFile(upleft,"\pHelp",NIL,1,fileType,
  178.                             NIL,&filetry);
  179.         DisposDialog(dptr);
  180.         if(filetry.good)
  181.         {    SetVol(volName,filetry.vRefNum);
  182.             if((helpResNum=OpenResFile(filetry.fName))<0)
  183.                 return(RsrcFileErr);
  184.         }
  185.         else
  186.             return(QuitHelp);
  187.     }
  188.     
  189.     GLhelpMenu=NewMenu(HELPMENU,"\pHelp");
  190.     AddResMenu(GLhelpMenu,'HMgr');
  191.     
  192.     return(TRUE);
  193. }
  194.  
  195. /***********************************************************
  196.     DIsplay dialog box and select help topics
  197.     text1, text2, and text3 are three lines of text to
  198.         appear in the dialog box
  199.     If topic selected return helpTopic, if help canceled
  200.         return QuitHelp, if error occurs return error code
  201. ***********************************************************/
  202.  
  203. static GetHelpTopic(helpTopic,text1,text2,text3,helpMenu)
  204.     int helpTopic;
  205.     char *text1,*text2,*text3;
  206.     MenuHandle helpMenu;
  207. {
  208.     DialogPtr dptr;
  209.     int ditem;
  210.     int numHelp=CountMItems(helpMenu);
  211.     register int i;
  212.     ListHandle helpList;
  213.     DlogIHdl helpInfo;
  214.     Point cSize;
  215.     Cell theCell;
  216.     char helpItem[80];
  217.     Rect dataBounds,helpDestRect;
  218.     HTHdl HT;
  219.     
  220.     HT=(HTHdl)GetResource('HTpl',TEMPLATE);
  221.     if(ResError()!=noErr)
  222.         return(TemplateErr);
  223.     
  224.     dptr=GetNewDialog((**HT).topicsID,NIL,-1L);
  225.     SetPort(dptr);
  226.     FrameDefaultButton(dptr);
  227.     
  228.     /*    Draw three text strings    */
  229.     MoveTo((**HT).text1Loc.h,(**HT).text1Loc.v);
  230.     DrawString(text1);
  231.     MoveTo((**HT).text2Loc.h,(**HT).text2Loc.v);
  232.     DrawString(text2);
  233.     MoveTo((**HT).text3Loc.h,(**HT).text3Loc.v);
  234.     DrawString(text3);
  235.     
  236.     TextFont((**HT).topicFont);
  237.     TextSize((**HT).topicSize);
  238.     TextFace(0);
  239.     SetRect(&helpDestRect,(**HT).topicRect.left,
  240.         (**HT).topicRect.top,(**HT).topicRect.right,
  241.         (**HT).topicRect.bottom);
  242.     FrameRect(&helpDestRect);
  243.  
  244.     /*    Initilize new list manger record */
  245.     InsetRect(&helpDestRect,1,1);
  246.     helpDestRect.right-=14;    
  247.     SetRect(&dataBounds,0,0,1,numHelp);
  248.     cSize.h=cSize.v=0;
  249.     helpList=LNew(&helpDestRect,&dataBounds,cSize,0,
  250.                 (WindowPtr)dptr,TRUE,FALSE,FALSE,TRUE);
  251.     if(helpList==NIL)
  252.     {    DisposDialog(dptr);
  253.         return(TopicsDlogErr);
  254.     }
  255.  
  256.     /* Initialise dialog info record */    
  257.     helpInfo=(DlogIHdl)NewHandle((Size)sizeof(DlogInfo));
  258.     if(helpInfo==NIL)
  259.     {    LDispose(helpList);
  260.         DisposDialog(dptr);
  261.         return(TopicsDlogErr);
  262.     }
  263.     SetWRefCon(dptr,(long)helpInfo);
  264.     (**helpInfo).helpList=helpList;
  265.     (**helpInfo).helpDlogType=HELPTOPICS;
  266.  
  267.     /*    Fill the list    */    
  268.     theCell.h=0;
  269.     for(i=1;i<=numHelp;i++)
  270.     {    GetItem(helpMenu,i,helpItem);
  271.         theCell.v=i-1;
  272.         LSetCell(&helpItem[1],(int)helpItem[0],
  273.                                     theCell,helpList);
  274.     }
  275.     (**helpList).selFlags=lOnlyOne;
  276.     theCell.v=helpTopic-1;
  277.     LSetSelect(TRUE,theCell,helpList);
  278.     LAutoScroll(helpList);
  279.                         
  280.     do
  281.     {    ModalDialog(&helpFilter,&ditem);
  282.         if(ditem==OK)
  283.         {    theCell.h=theCell.v=0;
  284.             LGetSelect(TRUE,&theCell,helpList);
  285.             helpTopic=theCell.v+1;
  286.         }
  287.     } while (ditem>Cancel);
  288.  
  289.     DisposHandle(helpInfo);
  290.     LDispose(helpList);
  291.     DisposDialog(dptr);
  292.     if(ditem==OK)
  293.         return(helpTopic);
  294.     else    
  295.         return(QuitHelp);
  296. }
  297.  
  298. /***********************************************************
  299.     Filter Help dialog events
  300.     On mouseDown: call LClick in HELPTOPICS dialogs
  301.                   call HelpDoScroll in HELPWINDOW dialogs
  302.     On keyDown: check for return or enter
  303. ***********************************************************/
  304.  
  305. pascal Boolean helpFilter(dptr,eventp,itemHit)
  306.     DialogPtr dptr;
  307.     EventRecord *eventp;
  308.     int *itemHit;
  309. {
  310.     char theChar;
  311.     Point where;
  312.     DlogIHdl helpInfo=(DlogIHdl)GetWRefCon(dptr);
  313.  
  314.     switch(eventp->what)
  315.     {    case mouseDown:
  316.             if((**helpInfo).helpDlogType==HELPTOPICS)
  317.             {    where=eventp->where;
  318.                 GlobalToLocal(&where);
  319.                 if(LClick(where,eventp->modifiers,
  320.                                 (**helpInfo).helpList))
  321.                 {    *itemHit=1;
  322.                     return(TRUE);
  323.                 }
  324.             }
  325.             else
  326.             {    if(HelpDoScroll(dptr,eventp->where,
  327.                                     helpInfo))
  328.                 {    *itemHit=11;
  329.                     return(TRUE);
  330.                 }
  331.             }    
  332.             break;
  333.         case autoKey:
  334.         case keyDown:
  335.             theChar=eventp->message&charCodeMask;
  336.             if(theChar==13||theChar==3)
  337.             {    *itemHit=1;
  338.                 return(TRUE);
  339.             }
  340.             break;
  341.         default:
  342.             break;
  343.     }
  344.     return(FALSE);
  345. }
  346.  
  347. /***********************************************************
  348.     Show the help topic number helpTopic
  349.     if Topics selected return helptopic, if help canceled
  350.         return QuitHelp, if error occurs return error code
  351. ***********************************************************/
  352.  
  353. static ShowHelpTopic(helpTopic,styleText,helpMenu)
  354.     int helpTopic;
  355.     Boolean styleText;
  356.     MenuHandle helpMenu;
  357. {
  358.     char resName[80],cTitle[5];
  359.     int ditem,helpError;
  360.     int numHelp=CountMItems(helpMenu);
  361.     DialogPtr dptr;
  362.     DlogIHdl helpInfo;
  363.     ControlHandle ScrollHdl;
  364.     Rect helpDestRect,scrollRect;
  365.     Boolean textWindow;
  366.     TEHandle helphTE;
  367.     HTHdl HT=(HTHdl)GetResource('HTpl',TEMPLATE);
  368.     
  369.     dptr=GetNewDialog((**HT).infoID,NIL,-1L);
  370.     SetPort(dptr);
  371.     FrameDefaultButton(dptr);
  372.     GetShowTitle(resName,helpTopic,helpMenu);
  373.     
  374.     SetRect(&helpDestRect,(**HT).textRect.left,
  375.         (**HT).textRect.top,(**HT).textRect.right,
  376.         (**HT).textRect.bottom);
  377.     FrameRect(&helpDestRect);
  378.     
  379.     /*    Set up scroll bar and text destRect */
  380.     SetRect(&scrollRect,helpDestRect.right-16,
  381.             helpDestRect.top,helpDestRect.right,
  382.                             helpDestRect.bottom);
  383.     InsetRect(&helpDestRect,1,1);
  384.     helpDestRect.left+=4;
  385.     helpDestRect.right=scrollRect.left-4;
  386.     cTitle[0]=0;
  387.     ScrollHdl=NewControl(dptr,&scrollRect,
  388.             cTitle,1,0,0,0,scrollBarProc,0);
  389.     Draw1Control(ScrollHdl);
  390.  
  391.     /*    Initialize Text Edit record    */    
  392.     if(styleText)
  393.         helphTE=TEStylNew(&helpDestRect,&helpDestRect);
  394.     else
  395.         helphTE=TENew(&helpDestRect,&helpDestRect);
  396.     if((helphTE==NIL)||(ScrollHdl==NIL))
  397.     {    DisposDialog(dptr);
  398.         return(TextDlogErr);
  399.     }
  400.  
  401.     /* Initalize Dialog info record    */    
  402.     helpInfo=(DlogIHdl)NewHandle((Size)sizeof(DlogInfo));
  403.     if(helpInfo==NIL)
  404.     {    TEDispose(helphTE);
  405.         DisposDialog(dptr);
  406.         return(TextDlogErr);
  407.     }
  408.     SetWRefCon(dptr,(long)helpInfo);
  409.     (**helpInfo).helpDlogType=HELPWINDOW;
  410.     (**helpInfo).ScrollHdl=ScrollHdl;
  411.     (**helpInfo).linesVis=(helpDestRect.bottom-
  412.                                 helpDestRect.top)/ScrlLine;
  413.     (**helpInfo).hTE=helphTE;
  414.     (**helpInfo).helpPict=NIL;
  415.     
  416.     if(helpError=InsertHelpText(resName,styleText,
  417.                                     helpInfo,helphTE))
  418.     {    DisposHandle(helpInfo);
  419.         TEDispose(helphTE);
  420.         DisposDialog(dptr);
  421.         return(helpError);
  422.     }
  423.     
  424.     do
  425.     {    ModalDialog(&helpFilter,&ditem);
  426.         if((ditem==NEXT)||(ditem==PREVIOUS))
  427.         {    if(ditem==NEXT) helpTopic++;
  428.             if(ditem==PREVIOUS) helpTopic--;
  429.             if(helpTopic>numHelp) helpTopic=1;
  430.             if(helpTopic<1) helpTopic=numHelp;
  431.             GetShowTitle(resName,helpTopic,helpMenu);
  432.             ClearPict(helpInfo);
  433.             if(helpError=InsertHelpText(resName,styleText,
  434.                                         helpInfo,helphTE))
  435.             {    helpTopic=helpError;
  436.                 ditem=TOPICS;
  437.             }
  438.         }
  439.     } while ((ditem!=TOPICS)&&(ditem!=HELPCANCEL));
  440.  
  441.     ClearPict(helpInfo);
  442.     DisposHandle(helpInfo);
  443.     TEDispose(helphTE);    
  444.     DisposDialog(dptr);
  445.     if(ditem==TOPICS)    
  446.         return(helpTopic);
  447.     else
  448.         return(QuitHelp);
  449. }
  450.  
  451. /***********************************************************
  452.     Get and show help title - if title is too long, attempt
  453.     is made to stop before first dash in help title
  454. ***********************************************************/
  455.  
  456. static GetShowTitle(resName,helpTopic,helpMenu)
  457.     char *resName;
  458.     int helpTopic;
  459.     MenuHandle helpMenu;
  460. {
  461.     GrafPtr curPort;
  462.     char showName[80];
  463.     register int i,dashLoc=0;
  464.     Rect titleRect;
  465.     HTHdl HT=(HTHdl)GetResource('HTpl',TEMPLATE);
  466.     
  467.     SetRect(&titleRect,(**HT).titleRect.left,
  468.         (**HT).titleRect.top,(**HT).titleRect.right,
  469.         (**HT).titleRect.bottom);
  470.     GetItem(helpMenu,helpTopic,resName);
  471.     showName[0]=resName[0];
  472.     for(i=1;i<=resName[0];i++)
  473.     {    showName[i]=resName[i];
  474.         if((dashLoc==0)&&(showName[i]=='-'))
  475.             dashLoc=i;
  476.     }
  477.     TextFont((**HT).titleFont);
  478.     TextSize((**HT).titleSize);
  479.     TextFace((**HT).titleFace);
  480.     if(StringWidth(showName)>
  481.                 (titleRect.right-titleRect.left))
  482.     {    if(dashLoc!=0)
  483.             showName[0]=dashLoc-1;
  484.     }
  485.  
  486.     EraseRect(&titleRect);
  487.     ClipRect(&titleRect);
  488.     MoveTo(titleRect.left,titleRect.top+(**HT).titleSize);
  489.     DrawString(showName);
  490.     GetPort(&curPort);
  491.     ClipRect(&curPort->portRect);
  492.     TextFont((**HT).textFont);
  493.     TextSize((**HT).textSize);
  494.     TextFace(0);
  495. }
  496.  
  497. /***********************************************************
  498.     Load text in named HMgr resource (resName) into the
  499.     text edit record. Format of HMgr resource given in
  500.     documentation. If load sucessful return FALSE. If
  501.     error occurs return error code.
  502. ***********************************************************/
  503.  
  504. static InsertHelpText(resName,styleText,helpInfo,helphTE)
  505.     char *resName;
  506.     Boolean styleText;
  507.     DlogIHdl helpInfo;
  508.     TEHandle helphTE;
  509. {
  510.     Handle resHdl,newText;
  511.     TEStyleHandle stHdl,newstHdl;
  512.     STHandle stabHdl,newstabHdl;
  513.     LHHandle lhTab;
  514.     NullStHandle nullStyle;
  515.     TextStyle newStyle;
  516.     long *lptr;
  517.     char *rptr;
  518.     int curValue,lineHeight,totalLines;
  519.     int totalHeight,horiz,vert,lm,pictID;
  520.     int *picSize;
  521.     Rect *rectPtr;
  522.     PicHandle helpPict;
  523.     Rect dest;
  524.     Size hSize;
  525.     HTHdl HT=(HTHdl)GetResource('HTpl',TEMPLATE);
  526.  
  527.     resHdl=GetNamedResource('HMgr',resName);
  528.     if(ResError()!=noErr)
  529.         return(HMgrNotFound);
  530.     if(SizeResource(resHdl)==2)    /* If true load in PICT */
  531.         return(InsertHelpPict(resHdl,helpInfo,helphTE));
  532.     
  533.     if(styleText)        
  534.     {    stHdl=GetStylHandle(helphTE);
  535.         stabHdl=(**stHdl).styleTab;
  536.         lhTab=(**stHdl).lhTab;
  537.         nullStyle=(**stHdl).nullStyle;
  538.     }
  539.  
  540.     /*    Get the style table    */
  541.     HLock(resHdl);
  542.     rptr=(char *)(*resHdl);
  543.     lptr=(long *)rptr;
  544.     rptr+=(int)sizeof(long);
  545.     if(styleText)
  546.     {    newstHdl=(TEStyleHandle)
  547.                     NewHandle(hSize=(Size)(*lptr));
  548.         if(MemError()!=noErr)
  549.         {    HUnlock(resHdl);
  550.             ReleaseResource(resHdl);
  551.             return(TextInsErr);
  552.         }
  553.         HLock(newstHdl);
  554.         BlockMove(rptr,(char *)(*newstHdl),hSize);
  555.         HUnlock(newstHdl);
  556.         (**newstHdl).lhTab=lhTab;
  557.         (**newstHdl).nullStyle=nullStyle;
  558.     }
  559.     rptr+=(int)(*lptr);
  560.  
  561.     /*    Get style runs    */
  562.     lptr=(long *)rptr;
  563.     rptr+=(int)sizeof(long);
  564.     if(styleText)
  565.     {    newstabHdl=(STHandle)NewHandle(hSize=(Size)(*lptr));
  566.         if(MemError()!=noErr)
  567.         {    HUnlock(resHdl);
  568.             ReleaseResource(resHdl);
  569.             DisposHandle(newstHdl);
  570.             return(TextInsErr);
  571.         }
  572.         HLock(newstabHdl);
  573.         BlockMove(rptr,(char *)(*newstabHdl),hSize);
  574.         HUnlock(newstabHdl);
  575.         (**newstHdl).styleTab=newstabHdl;
  576.     }
  577.     rptr+=(int)(*lptr);
  578.  
  579.     /*    Get the text    */        
  580.     lptr=(long *)rptr;
  581.     rptr+=(int)sizeof(long);
  582.     newText=NewHandle(hSize=(Size)(*lptr));
  583.     if(MemError()!=noErr)
  584.     {    HUnlock(resHdl);
  585.         ReleaseResource(resHdl);
  586.         if(styleText)
  587.         {    DisposHandle(newstHdl);
  588.             DisposHandle(newstabHdl);
  589.         }
  590.         return(TextInsErr);
  591.     }
  592.     HLock(newText);
  593.     BlockMove(rptr,(char *)(*newText),hSize);
  594.     HUnlock(newText);
  595.     HUnlock(resHdl);
  596.     ReleaseResource(resHdl);
  597.  
  598.     EraseRect(&(**helphTE).viewRect);        
  599.     DisposHandle((**helphTE).hText);
  600.     (**helphTE).hText=newText;
  601.     if(styleText)
  602.     {    SetStylHandle(newstHdl,helphTE);
  603.         DisposHandle(stabHdl);
  604.     }
  605.     
  606.     TECalText(helphTE);
  607.     (**helphTE).destRect=(**helphTE).viewRect;
  608.     SetCtlValue((**helpInfo).ScrollHdl,0);
  609.  
  610.     /*    Find total lines and set scroll bar maximm    */
  611.     if((lineHeight=(**helphTE).lineHeight)<0)
  612.     {    totalHeight=TEGetHeight((long)(**helphTE).nLines,
  613.                         (long)1,helphTE);
  614.         totalLines=totalHeight/ScrlLine+1;
  615.     }
  616.     else
  617.     {    if(lineHeight==ScrlLine)
  618.             totalLines=(**helphTE).nLines;
  619.         else
  620.         {    totalHeight=(**helphTE).nLines*lineHeight;
  621.             totalLines=totalHeight/ScrlLine+1;
  622.         }
  623.     }
  624.     if(totalLines>(**helpInfo).linesVis)
  625.         SetCtlMax((**helpInfo).ScrollHdl,
  626.                 totalLines-(**helpInfo).linesVis);
  627.     else
  628.         SetCtlMax((**helpInfo).ScrollHdl,0);
  629.     TEUpdate(&(**helphTE).viewRect,helphTE);
  630.  
  631.     return(FALSE);
  632. }
  633.  
  634. /******************************************************************
  635.     This help info is in the form of a PICT
  636. ******************************************************************/
  637.  
  638. static InsertHelpPict(resHdl,helpInfo,helphTE)
  639.     Handle resHdl;
  640.     DlogIHdl helpInfo;
  641.     TEHandle helphTE;
  642. {
  643.     int pictID,horiz,vert,tm,lm,totalLines;
  644.     Rect *rectPtr,pictRect;
  645.     PicHandle helpPict;
  646.     GrafPtr curPort;
  647.     
  648.     pictID=*((int *)(*resHdl));
  649.     ReleaseResource(resHdl);
  650.     helpPict=GetPicture(pictID);
  651.     if(helpPict==NIL)
  652.         return(PictNotFound);
  653.  
  654.     HLock(helpPict);
  655.     rectPtr=(Rect *)((int *)*helpPict+1);
  656.     horiz=rectPtr->right-rectPtr->left;
  657.     lm=((**helphTE).viewRect.right-(**helphTE).viewRect.left-horiz)/2;
  658.     if(lm<0) lm=0;
  659.     lm+=(**helphTE).viewRect.left;
  660.     vert=rectPtr->bottom-rectPtr->top;
  661.     tm=(**helphTE).viewRect.top+1;
  662.     SetRect(&pictRect,lm,tm,lm+horiz,tm+vert);
  663.     HUnlock(helpPict);
  664.     EraseRect(&(**helphTE).viewRect);
  665.     ClipRect(&(**helphTE).viewRect);
  666.     DrawPicture(helpPict,&pictRect);
  667.     GetPort(&curPort);
  668.     ClipRect(&curPort->portRect);
  669.     
  670.     (**helpInfo).helpPict=helpPict;
  671.     (**helpInfo).pictRect=pictRect;
  672.     SetCtlValue((**helpInfo).ScrollHdl,0);
  673.     totalLines=vert/ScrlLine+1;
  674.     if(totalLines>(**helpInfo).linesVis)
  675.         SetCtlMax((**helpInfo).ScrollHdl,
  676.                 totalLines-(**helpInfo).linesVis);
  677.     else
  678.         SetCtlMax((**helpInfo).ScrollHdl,0);
  679.         
  680.     return(FALSE);
  681. }
  682.  
  683. /***********************************************************
  684.     Release PICT resource if one is being used
  685. ***********************************************************/
  686.  
  687. static ClearPict(helpInfo)
  688.     DlogIHdl helpInfo;
  689. {
  690.     if((**helpInfo).helpPict!=NIL)
  691.     {    ReleaseResource((**helpInfo).helpPict);
  692.         (**helpInfo).helpPict=NIL;
  693.     }
  694. }
  695.  
  696. /***********************************************************
  697.     Frame the default dialog box button
  698. ***********************************************************/
  699.  
  700. static FrameDefaultButton(dptr)
  701.     DialogPtr dptr;
  702. {
  703.     Rect OKrect;
  704.     int itype;
  705.     Handle ihdl;
  706.     
  707.     PenSize(3,3);
  708.     GetDItem(dptr,OK,&itype,&ihdl,&OKrect);
  709.     InsetRect(&OKrect,-4,-4);
  710.     FrameRoundRect(&OKrect,16,16);
  711.     PenSize(1,1);
  712. }
  713.  
  714. /***********************************************************
  715.     Do scrolling, return TRUE if scrolled or FALSE if not 
  716. ***********************************************************/
  717.  
  718. static HelpDoScroll(theWindow,where,helpInfo)
  719.     WindowPtr theWindow;
  720.     long where;
  721.     DlogIHdl helpInfo;
  722. {
  723.     int partCode,oldValue,newValue,units;
  724.     ControlHandle control;
  725.     
  726.     GlobalToLocal(&where);
  727.     partCode=FindControl(where,theWindow,&control);
  728.     if(partCode==0) return(FALSE);
  729.     if(control!=(**helpInfo).ScrollHdl) return(FALSE);
  730.         
  731.     switch(partCode)
  732.     {    case inUpButton:
  733.         case inDownButton:
  734.         case inPageUp:
  735.         case inPageDown:
  736.             switch(partCode)
  737.             {    case inUpButton:
  738.                     (**helpInfo).scrollAmt=-1;
  739.                     break;
  740.                 case inDownButton:
  741.                     (**helpInfo).scrollAmt=1;
  742.                     break;
  743.                 case inPageUp:
  744.                     (**helpInfo).scrollAmt=
  745.                                     -(**helpInfo).linesVis;
  746.                     break;
  747.                 case inPageDown:
  748.                     (**helpInfo).scrollAmt=
  749.                                     (**helpInfo).linesVis;
  750.                     break;
  751.             }
  752.             (**helpInfo).scrollCode=partCode;
  753.             TrackControl(control,where,&HelpScrollProc);
  754.             break;
  755.         case inThumb:
  756.             oldValue=GetCtlValue(control);
  757.             if(TrackControl(control,where,-1L))
  758.             {    newValue=GetCtlValue(control);
  759.                 if(units=oldValue-newValue)
  760.                     HelpScroll(units,helpInfo);
  761.             }
  762.             break;
  763.         default:
  764.             break;
  765.     }
  766.     return(TRUE);
  767. }
  768.  
  769. /***********************************************************
  770.     Action procedure for scrolling
  771. ***********************************************************/
  772.  
  773. pascal void HelpScrollProc(control,theCode)
  774.     ControlHandle control;
  775.     int theCode;
  776. {
  777.     int max,oldValue,newValue,units;
  778.     WindowPtr ctrlWindow=(*control)->contrlOwner;
  779.     DlogIHdl helpInfo=(DlogIHdl)GetWRefCon(ctrlWindow);
  780.     
  781.     if(theCode==(**helpInfo).scrollCode)
  782.     {    oldValue=GetCtlValue(control);
  783.         newValue=oldValue+(**helpInfo).scrollAmt;
  784.         if(newValue<0) newValue=0;
  785.         max=GetCtlMax(control);
  786.         if(newValue>max) newValue=max;
  787.         SetCtlValue(control,newValue);
  788.         if(units=oldValue-newValue)
  789.             HelpScroll(units,helpInfo);
  790.     }
  791. }
  792.  
  793. /***********************************************************
  794.     Scroll the help window by units lines
  795. ***********************************************************/
  796.  
  797. static HelpScroll(units,helpInfo)
  798.     int units;
  799.     DlogIHdl helpInfo;
  800. {
  801.     RgnHandle tmpRgn;
  802.     GrafPtr curPort;
  803.     Rect pictRect,viewRect;
  804.     int tm,absunits=units<0 ? -units : units;
  805.  
  806.     if((**helpInfo).helpPict==NIL)
  807.         TEScroll(0,ScrlLine*units,(**helpInfo).hTE);
  808.     else
  809.     {    viewRect=(**((**helpInfo).hTE)).viewRect;
  810.         if(absunits>(**helpInfo).linesVis)
  811.             InvalRect(&viewRect);
  812.         else
  813.         {    tmpRgn=NewRgn();
  814.             ScrollRect(&viewRect,0,ScrlLine*units,tmpRgn);
  815.             InvalRgn(tmpRgn);
  816.             DisposeRgn(tmpRgn);
  817.         }
  818.         GetPort(&curPort);
  819.         BeginUpdate(curPort);
  820.             ClipRect(&viewRect);
  821.             EraseRect(&viewRect);
  822.             tm=GetCtlValue((**helpInfo).ScrollHdl)*ScrlLine;
  823.             pictRect=(**helpInfo).pictRect;        
  824.             OffsetRect(&pictRect,0,-tm);
  825.             DrawPicture((**helpInfo).helpPict,&pictRect);
  826.             ClipRect(&curPort->portRect);
  827.         EndUpdate(curPort);
  828.     }
  829. }
  830.